perm filename READIN.IAN[B2,JMC] blob
sn#760768 filedate 1984-07-08 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00003 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 Numval code
C00006 00003 Numval code
C00008 ENDMK
C⊗;
Numval code
As another example of a combined numeric and symbolic computation, we give
an evaluator for expressions with sums and products. We shall also take this as
an opportunity to demonstrate the use of abstract syntax, a subject that we shall
devote a whole chapter to later in the book. The expressions that we shall be
evaluating are built up from symbols denoting variables and integer constants in the
following fashion
1. A symbol or a number is an expression.
2. If e1, e2, .. en are expressions then so are (PLUS e1 e2 .. en) and
(TIMES e1 e2 .. en)
Thus a list of expressions beginning with either the symbol PLUS or the symbol TIMES
is an expression . The former represents the sum of these expressions while the
later represents the product of them. Another way to describe abstractly
our domain of expressions is to use the constructor functions MKSUM and MKPROD
where
MKSUM[x] ← CONS[PLUS x] and MKPROD[x] ← CONS[TIMES x]
Using this method the above definition becomes
1'. A symbol or a number is an expression.
2'. If elist is a list of expressions then MKSUM[elist] and MKPROD[elist] are
expressions.
The reason why one would choose the latter method is that it enables one to write
the program NUMVAL in a style that emphasizes the algorithm rather than the
representation of data . It also allows one to alter the representation
at a later date without having to change the program, except for modifying the
definitions of the functions that deal explicitly with the representation.
In writing the program NUMVAL we shall also need the functions ISSUM, ISPROD,
ISNUM,ISVAR, and ARGLIST. Using the above representation as lists these are
defined as
ISSUM[x] ← eq[ax,PLUS]
ISPROD[x] ← eq[ax,TIMES]
ISNUM[x] ← numberp x
ISVAR[x] ← at x and not numberp x
ARGLIST[x] ← dx
Now in order to evaluate an expression ...(assoc stuff)....into most LISP
systems.
The interpreter NUMVAL can now be defined.
NUMVAL[exp, a] ← if ISNUM[e] then e else
if ISVAR[e] then dassoc[e,a] else
if ISSUM[e] then EVPLUS[ARGLIST[e],a] else
if ISPROD[e] then EVPROD[ARGLIST[e],a]
where
EVPLUS[u,a] ← if n u then 0 else NUMVAL[au,a] + EVPLUS[du,a]
EVPROD[u,a] ← if n u then 1 else NUMVAL[au,a] . EVPROD[du,a]
Exercise
Rewrite NUMVAL using mapping functions.
Numval code
(defun mksum (x) (cons 'plus x))
(defun mkprod (x) (cons 'times x))
(defun issum (x) (eq (car x) 'plus))
(defun isprod (x) (eq (car x) 'times))
(defun isnum (x) (numberp x))
(defun isvar (x) (and (atom x) (not (numberp x))))
(defun arglist (x) (cdr x))
(defun numval (x y) (if (isnum x) x
(if (isvar x) (cdr (assoc x y))
(if (issum x) (evplus (arglist x) y)
(if (isprod x) (evprod (arglist x) y) 'error) ) ) ) )
(defun evplus (x y) (if (null x) 0 (plus (numval (car x) y) (evplus (cdr x) y))))
(defun evprod (x y) (if (null x) 1 (times (numval (car x) y) (evprod (cdr x) y))))
(setq y '( (x . 1) (y . 2) (z . 3) ))
(setq e1 '(plus x x x y (times z z)))
(setq e2 '(times x y z 7 (times)))
(setq e3 '(plus))
(numval e1 y)
(numval e2 y)
(numval e3 y)
9
(times 6 7)
(times 1 2 3 7 1)